/**
 * Generali Solutions d'assurances - Tous droits réservés &copy; 2007 - 2010
 */
package fr.generali.accueilclient.client.services.impl;

import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Service;

import fr.generali.accueilclient.client.om.IContact;
import fr.generali.accueilclient.client.om.IPersonne;
import fr.generali.accueilclient.client.services.IClientService;
import fr.generali.accueilclient.commun.exception.AccueilClientBusinessException;
import fr.generali.accueilclient.commun.exception.AccueilClientModificationContactException;
import fr.generali.accueilclient.commun.exception.AccueilClientTechnicalException;
import fr.generali.refservcommuns.rce.chgmtnature.client.ChangementNatureClient;
import fr.generali.refservcommuns.rce.chgmtnature.services.IChangementNatureClientWebService;
import fr.generali.refservcommuns.rce.demat.creationpersonne.creationpersonneservice.CreerPersonne;
import fr.generali.refservcommuns.rce.demat.creationpersonne.creationpersonneservice.CreerPersonneResponse;
import fr.generali.refservcommuns.rce.demat.creationpersonne.services.ICreationPersonneDematWebService;
import fr.generali.refservcommuns.rce.demat.creationpersonne.dtocreerpersonne.DtoDossierP12;
import fr.generali.refservcommuns.rce.desactivation.desactivationservice.Desactivation;
import fr.generali.refservcommuns.rce.desactivation.services.IDesactivationWebService;
import fr.generali.refservcommuns.rce.gestiondocument.dtogestiondocument.DtoDossierP15;
import fr.generali.refservcommuns.rce.gestiondocument.dtogestiondocument.DtoListeDossierP15;
import fr.generali.refservcommuns.rce.gestiondocument.dct.DtoPieceIdentite;
import fr.generali.refservcommuns.rce.gestiondocument.gestiondocumentservice.GestionDocument;
import fr.generali.refservcommuns.rce.gestiondocument.gestiondocumentservice.GestionDocumentResponse;
import fr.generali.refservcommuns.rce.gestiondocument.services.IGestionDocumentWebService;
import fr.generali.refservcommuns.rce.gestiondocument.services.TechnicalFault;
import fr.generali.refservcommuns.rce.gestiondocument.services.WsRceBusinessException;
import fr.generali.refservcommuns.rce.demat.modificationpersonne.services.IModificationPersonneDematWebService;
import fr.generali.refservcommuns.rce.demat.modificationpersonne.modificationpersonneservice.ModifierPersonne;
import fr.generali.refservcommuns.rce.demat.modificationpersonne.modificationpersonneservice.ModifierPersonneResponse;
import fr.generali.refservcommuns.rce.demat.modificationpersonne.dtomodifpersonne.DtoDossierP13;

/**
 * Implémentation de {@link IClientService}
 * 
 * @author selrhazala
 */
@Service
public class ClientService implements IClientService {

    /**
     * LOGGER
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(ClientService.class);

    /**
     * Service de création de personne
     */
    @Autowired
    @Qualifier("P12")
    private ICreationPersonneDematWebService p12;

    /**
     * Service de modification de personne
     */
    @Autowired
    @Qualifier("P13")
    private IModificationPersonneDematWebService p13;

    /**
     * Service de gestion des documents
     */
    @Autowired
    @Qualifier("P15")
    private IGestionDocumentWebService p15;

    /**
     * Service de désactivation contact et rib
     */
    @Autowired
    @Qualifier("P18")
    private IDesactivationWebService p18;

    /**
     * Service de changement de nature client
     */
    @Autowired
    @Qualifier("P20")
    private IChangementNatureClientWebService p20;

    /**
     * Assembler en entrée de P12
     */
    @Autowired
    @Qualifier("personneToCreerPersonneConverter")
    private Converter<IPersonne, CreerPersonne> personneToCreerPersonneConverter;

    /**
     * Assembler en entrée de P13
     */
    @Autowired
    @Qualifier("personneToModifierPersonneConverter")
    private Converter<IPersonne, ModifierPersonne> personneToModifierPersonneConverter;

    /**
     * Assembler en entrée de P15
     */
    @Autowired
    @Qualifier("contactToGestionDocumentConverter")
    private Converter<IContact, GestionDocument> contactToGestionDocumentConverter;

    /**
     * Assembler en entrée de P18
     */
    @Autowired
    @Qualifier("personneToDesactivationConverter")
    private Converter<IPersonne, Desactivation> personneToDesactivationConverter;

    /**
     * Assembler en entrée de P18
     */
    @Autowired
    @Qualifier("contactToDesactivationContactConverter")
    private Converter<IContact, Desactivation> contactToDesactivationContactConverter;

    /**
     * Assembler en entrée de P18
     */
    @Autowired
    @Qualifier("personneToChangementNatureClientConverter")
    private Converter<IPersonne, ChangementNatureClient> personneToChangementNatureClientConverter;

    /**
     * @param client le client
     * @return l'id client physique en position 0 et l'id client morale en
     *         position 1 car 2 id dans le cas d'un PRO
     * @throws AccueilClientBusinessException exception fonctionnelle
     */
    public String[] creerClient(IPersonne client) throws AccueilClientBusinessException {

        CreerPersonneResponse creerPersonneResponse = null;

        try {
            creerPersonneResponse = p12.creerPersonne(personneToCreerPersonneConverter.convert(client));
        } catch (fr.generali.refservcommuns.rce.demat.creationpersonne.services.TechnicalFault e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), StringUtils.EMPTY, e);
        } catch (fr.generali.refservcommuns.rce.demat.creationpersonne.services.WsRceBusinessException e) {
            LOGGER.debug(e.getMessage());
            throw new AccueilClientBusinessException(e.getMessage(), e);
        }

        return getIdentifiantCreerPersonneResponse(creerPersonneResponse);
    }

    /**
     * @param creerPersonneResponse la réponse retournée par le WS
     * @return l'id client physique en position 0 et l'id client morale en
     *         position 1 car 2 id dans le cas d'un PRO
     */
    private String[] getIdentifiantCreerPersonneResponse(CreerPersonneResponse creerPersonneResponse) {
        String idPhysique = StringUtils.EMPTY;
        String idMorale = StringUtils.EMPTY;

        if (creerPersonneResponse != null && creerPersonneResponse.getDtoListeDossierP12() != null
                        && CollectionUtils.isNotEmpty(creerPersonneResponse.getDtoListeDossierP12().getDossierP12())) {
            DtoDossierP12 dtoDossierP12 = creerPersonneResponse.getDtoListeDossierP12().getDossierP12().get(0);
            if (dtoDossierP12.getPersonnePhysique() != null) {
                idPhysique = dtoDossierP12.getPersonnePhysique().getIdentifiantPersonne();
                if (dtoDossierP12.getPersonneMorale() != null) {
                    idMorale = dtoDossierP12.getPersonneMorale().getIdentifiantPersonne();
                }
            } else if (dtoDossierP12.getPersonneMorale() != null) {
                idMorale = dtoDossierP12.getPersonneMorale().getIdentifiantPersonne();
            }
        }

        String[] stringIdClient = {idPhysique, idMorale };

        return stringIdClient;
    }

    /**
     * @param client le client
     * @return String la valeur retour
     * @throws AccueilClientBusinessException exception fonctionnelle
     */
    public String modifierClient(IPersonne client) throws AccueilClientBusinessException {
        ModifierPersonneResponse modifierPersonneResponse = null;

        try {
            modifierPersonneResponse = p13.modifierPersonne(personneToModifierPersonneConverter.convert(client));
        } catch (fr.generali.refservcommuns.rce.demat.modificationpersonne.services.TechnicalFault e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), StringUtils.EMPTY, e);
        } catch (fr.generali.refservcommuns.rce.demat.modificationpersonne.services.WsRceBusinessException e) {
            LOGGER.debug(e.getMessage());
            throw new AccueilClientBusinessException(e.getMessage(), e);
        }

        return getIdentifiantModifierPersonneResponse(modifierPersonneResponse);
    }

    /**
     * @param modifierPersonneResponse la réponse retournée par le WS
     * @return idRetour String
     */
    private String getIdentifiantModifierPersonneResponse(ModifierPersonneResponse modifierPersonneResponse) {
        String idRetour = StringUtils.EMPTY;

        if (modifierPersonneResponse != null
                        && modifierPersonneResponse.getDtoListeDossierP13() != null
                        && CollectionUtils.isNotEmpty(modifierPersonneResponse.getDtoListeDossierP13()
                                        .getDossierPersonne())) {
            DtoDossierP13 dtoDossierP13 = modifierPersonneResponse.getDtoListeDossierP13().getDossierPersonne().get(0);
            if (dtoDossierP13.getPersonnePhysique() != null) {
                idRetour = dtoDossierP13.getPersonnePhysique().getIdentifiantPersonne();
            } else if (dtoDossierP13.getPersonneMorale() != null) {
                idRetour = dtoDossierP13.getPersonneMorale().getIdentifiantPersonne();
            }
        }

        return idRetour;
    }

    /**
     * supprime le client courant
     * 
     * @param client le client
     * @throws AccueilClientBusinessException exception fonctionnelle
     */
    public void supprimerClient(IPersonne client) throws AccueilClientBusinessException {
        try {
            p18.desactivation(personneToDesactivationConverter.convert(client));
        } catch (fr.generali.refservcommuns.rce.desactivation.services.TechnicalFault e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), StringUtils.EMPTY, e);
        } catch (fr.generali.refservcommuns.rce.desactivation.services.WsRceBusinessException e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientModificationContactException(e.getMessage(), StringUtils.EMPTY, e);
        }
    }

    /**
     * @param contact le contact
     * @return String
     * @throws AccueilClientBusinessException exception fonctionnelle
     */
    public String gererDocument(IContact contact) throws AccueilClientBusinessException {
        GestionDocumentResponse gestionDocumentResponse = null;

        try {
            gestionDocumentResponse = p15.gestionDocument(contactToGestionDocumentConverter.convert(contact));
        } catch (TechnicalFault e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), StringUtils.EMPTY, e);
        } catch (WsRceBusinessException e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), StringUtils.EMPTY, e);
        }

        if (gestionDocumentResponse != null) {
            DtoListeDossierP15 dtoListeDossierP15 = gestionDocumentResponse.getDtoListeDossierP15();
            if (dtoListeDossierP15 != null) {
                List<DtoDossierP15> listeDossierP15 = dtoListeDossierP15.getDossierP15();
                if (CollectionUtils.isNotEmpty(listeDossierP15)) {
                    DtoDossierP15 dossierP15 = listeDossierP15.get(0);
                    List<DtoPieceIdentite> listePieceIdentite = null;
                    if (CollectionUtils.isNotEmpty(dossierP15.getDossierDocument().getPieceIdentite())) {
                        listePieceIdentite = dossierP15.getDossierDocument().getPieceIdentite();
                        if (CollectionUtils.isNotEmpty(listePieceIdentite)) {
                            DtoPieceIdentite document = listePieceIdentite.get(0);
                            return document.getNumeroOfficiel();
                        }
                    }
                }
            }
        }

        return StringUtils.EMPTY;
    }

    /**
     * @param contact le contact
     * @throws AccueilClientBusinessException exception fonctionnelle
     */
    public void desactiverDocument(IContact contact) throws AccueilClientBusinessException {
        try {
            p18.desactivation(contactToDesactivationContactConverter.convert(contact));
        } catch (fr.generali.refservcommuns.rce.desactivation.services.TechnicalFault e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), StringUtils.EMPTY, e);
        } catch (fr.generali.refservcommuns.rce.desactivation.services.WsRceBusinessException e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientModificationContactException(e.getMessage(), StringUtils.EMPTY, e);
        }
    }

    /**
     * @param client le client
     * @return String la valeur retour
     * @throws AccueilClientBusinessException exception fonctionnelle
     */
    public String changerNatureClient(IPersonne client) throws AccueilClientBusinessException {
        String idRetour = StringUtils.EMPTY;

        try {
            p20.changementNatureClient(personneToChangementNatureClientConverter.convert(client));
        } catch (fr.generali.refservcommuns.rce.chgmtnature.services.TechnicalFault e) {
            LOGGER.error(e.getMessage());
            throw new AccueilClientTechnicalException(e.getMessage(), StringUtils.EMPTY, e);
        } catch (fr.generali.refservcommuns.rce.chgmtnature.services.WsRceBusinessException e) {
            // Pas d'exception jetée ici car le ws lance une exception quand
            // Changement de nature non autorisé
            LOGGER.debug(e.getMessage());
            idRetour = "Changement de nature non autorisé par la Web Service";
        }

        return idRetour;
    }

}
